﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Common.Unit
{
    public static class FunctionExtend
    {
        #region Repeater 扩展
        /// <summary>
        /// 绑定单个对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="rep"></param>
        /// <param name="obj">要绑定的单个对象</param>
        public static void DataBind<T>(this System.Web.UI.WebControls.Repeater rep, T obj)
        {
            if (obj == null) return;
            List<T> list = new List<T>();
            list.Add(obj);
            rep.DataSource = list;
            rep.DataBind();
        }
        #endregion

        #region String扩展方法
        /// <summary>
        /// String扩展方法
        /// 截取前面len长度个字符
        /// </summary>
        /// <param name="len">长度</param>
        /// <returns></returns>
        public static string SubStr(this String str, int len)
        {
            if (string.IsNullOrEmpty(str)) return string.Empty;
            if (str.Length <= len) return str;
            return str.Substring(0, len);
        }

        /// <summary>
        /// String扩展方法
        /// </summary>
        /// <returns></returns>
        public static int GetInt(this String str)
        {
            return int.Parse(str);
        }
        public static int GetInt(this String str, int valueWhenNull)
        {
            int? v = str.GetIntOrNull();
            return v.HasValue ? v.Value : valueWhenNull;
        }


        /// <summary>
        /// String扩展方法
        /// </summary>
        /// <returns></returns>
        public static List<int> GetIntList(this String str, char spr)
        {
            List<int> a = new List<int>();
            if (str.IsEmptyOrNull()) return a;
            foreach (string s in str.Split(spr))
            {
                if (s.IsEmptyOrNull()) continue;
                a.Add(s.GetInt());
            }
            return a;
        }

        /// <summary>
        /// String扩展方法
        /// </summary>
        /// <returns></returns>
        public static int[] GetIntArray(this String str, char spr)
        {
            return str.GetIntList(spr).ToArray();
        }

        /// <summary>
        /// 将字符串按一定的固定位数的整数 
        /// 如 "111222333".GetIntArray(3) 分解成[111,222,333]
        /// </summary>
        /// <param name="str"></param>
        /// <param name="len">每个整数占的位数</param>
        /// <returns></returns>
        public static int[] GetIntArray(this String str, int len)
        {
            List<int> a = new List<int>();
            while (str.Length > 0)
            {
                a.Add(str.SubStr(Math.Min(len, str.Length)).GetInt());
                str = str.Remove(0, Math.Min(len, str.Length));
            }
            return a.ToArray();
        }

        /// <summary>
        /// String扩展方法
        /// </summary>
        /// <returns></returns>
        public static int? GetIntOrNull(this String str)
        {
            try
            {
                if (string.IsNullOrEmpty(str)) return null;
                return int.Parse(str);
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// String扩展方法
        /// </summary>
        /// <returns></returns>
        public static DateTime? GetDateTimeOrNull(this String str)
        {
            try
            {
                if (string.IsNullOrEmpty(str)) return null;
                return DateTime.Parse(str);
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// String扩展方法
        /// </summary>
        /// <returns></returns>
        public static DateTime GetDateTime(this String str)
        {
            return DateTime.Parse(str);
        }

        /// <summary>
        /// String扩展方法
        /// </summary>
        /// <returns></returns>
        public static bool IsMatch(this String str, string reg)
        {
            if (str.IsEmptyOrNull()) return false;
            return System.Text.RegularExpressions.Regex.IsMatch(str, reg);
        }
        /// <summary>
        /// String扩展方法
        /// </summary>
        /// <returns></returns>
        public static bool IsMatch(this String str, string reg, System.Text.RegularExpressions.RegexOptions options)
        {
            if (str.IsEmptyOrNull()) return false;
            return System.Text.RegularExpressions.Regex.IsMatch(str, reg, options);
        }

        /// <summary>
        /// String扩展方法
        /// </summary>
        /// <returns></returns>
        public static bool IsEmptyOrNull(this String str)
        {
            return string.IsNullOrEmpty(str);
        }

        /// <summary>
        /// String扩展方法
        /// </summary>
        /// <returns></returns>
        public static string IsEmptyOrNull(this String str, string v)
        {
            if (string.IsNullOrEmpty(str)) return v;
            return str;
        }

        /// <summary>
        /// String扩展方法
        /// </summary>
        /// <returns></returns>
        public static bool IsNotEmptyNotNull(this String str)
        {
            return !string.IsNullOrEmpty(str);
        }


        /// <summary>
        /// String扩展方法，当前对象为null时返回 string.Empty
        /// </summary>
        /// <returns></returns>
        public static string EmptyWhenIsNull(this String str)
        {
            if (str == null) return string.Empty;
            return str;
        }

        public static bool IsIn(this string str, string inStr)
        {
            return inStr.IndexOf(str) >= 0;
        }

        public static bool IsIn(this string str, string[] strArray)
        {
            return strArray.Count(a => a == str) > 0;
        }

        public static string UrlEncode(this String str, Encoding encoding)
        {
            return System.Web.HttpUtility.UrlEncode(str, encoding);
        }
        public static string UrlDecode(this String str, Encoding encoding)
        {
            return System.Web.HttpUtility.UrlDecode(str, encoding);
        }
        public static string HtmlEncode(this String str)
        {
            return System.Web.HttpUtility.HtmlEncode(str);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="str"></param>
        /// <param name="br">是否将换行符转换成&lt;br /&gt;</param>
        /// <returns></returns>
        public static string HtmlEncode(this String str, bool br)
        {
            str = System.Web.HttpUtility.HtmlEncode(str);
            if (!br) return str;
            return str.Replace("\r\n", "<br />").Replace("\n\r", "<br />").Replace("\r", "<br />").Replace("\n", "<br />");
        }
        public static string HtmlDecode(this String str)
        {
            return System.Web.HttpUtility.HtmlDecode(str);
        }

        #endregion

        /// <summary>
        /// 扩展方法：将数组转换成String
        /// </summary>
        /// <param name="list">List对象</param>
        /// <param name="seperate">分隔符</param>
        /// <returns></returns>
        public static string SeperateToString<T>(this T[] t, string seperate) where T : struct
        {
            string str = string.Empty;
            if (t == null || t.Length == 0) return str;
            foreach (T tValue in t)
            {
                str += seperate + tValue.ToString();
            }
            return str.Substring(seperate.Length);
        }

        /// <summary>
        /// 扩展方法：将数组转换成String
        /// </summary>
        /// <param name="list">List对象</param>
        /// <param name="seperate">分隔符</param>
        /// <returns></returns>
        public static string JoinToString(this string[] t, string seperate)
        {
            string str = string.Empty;
            if (t == null || t.Length == 0) return str;
            foreach (string tValue in t)
            {
                str += seperate + tValue.ToString();
            }
            return str.Substring(seperate.Length);
        }

        /// <summary>
        /// 扩展方法：将数组转换成SQL形式，
        /// 如["a","b","c"].JoinToParmsSQL(" and ") 结果为 "a=@a and b=@b and c=@c"
        /// </summary>
        /// <param name="list">List对象</param>
        /// <param name="seperate">分隔符</param>
        /// <returns></returns>
        public static string JoinToParmsSQL(this string[] t, string seperate)
        {
            string str = string.Empty;
            if (t == null || t.Length == 0)
                return str;
            foreach (string tValue in t)
            {
                if (tValue.Trim().IsEmptyOrNull()) continue;
                str += seperate + tValue.Trim().ToString() + "=@" + tValue.Trim().ToString();
            }
            return str.Substring(seperate.Length);
        }

        /// <summary>
        /// 冒泡排序，升序
        /// </summary>
        /// <param name="arry"></param>
        public static int[] BubbleSortASC(this int[] arry)
        {
            for (int i = arry.Length - 1; i >= 0; i--)
            {
                for (int j = 0; j < i; j++)
                {
                    if (arry[j] > arry[j + 1])
                    {
                        int k = arry[j + 1];
                        arry[j + 1] = arry[j];
                        arry[j] = k;
                    }
                }
            }
            return arry;
        }
        /// <summary>
        /// 冒泡排序，降序
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public static int[] BubbleSortDESC(this int[] arry)
        {
            for (int i = arry.Length - 1; i >= 0; i--)
            {
                for (int j = 0; j < i; j++)
                {
                    if (arry[j] < arry[j + 1])
                    {
                        int k = arry[j + 1];
                        arry[j + 1] = arry[j];
                        arry[j] = k;
                    }
                }
            }
            return arry;
        }

        /// <summary>
        /// 整数型枚举扩展方法，测试是否是数组的值之一
        /// </summary>
        /// <returns></returns>
        public static bool IsIn(this int v, params int[] values)
        {
            foreach (int i in values) if (i == v) return true;
            return false;
        }

        /// <summary>
        /// 整数型枚举扩展方法，测试是否是某整形枚举的值之一
        /// </summary>
        /// <returns></returns>
        public static bool IsValueOfEnum(this int v, Type enumType)
        {
            foreach (int i in Enum.GetValues(enumType)) if (i == v) return true;
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="v"></param>
        /// <param name="min"></param>
        /// <param name="max"></param>
        /// <param name="includeside">是否包含两头数值</param>
        /// <returns></returns>
        public static bool IsBetween(this int v, int min, int max, bool includeside)
        {
            if (includeside) return v >= min && v <= max;
            return v > min && v < max;
        }

        /// <summary>
        /// 反转指定的二进制位，二进制位存在则删除，二进制位不存在则设置
        /// </summary>
        /// <param name="v"></param>
        /// <param name="v2"></param>
        /// <returns></returns>
        public static int Toggle(this int v, int v2)
        {
            int v1 = (v & v2);  //已存在的位
            int v3 = (~v & v2);  //未存在的位
            v = (v & (~v1));  //清除已存在的位
            v = (v | v3);  //设置未存在的位
            return v;
        }


        /// <summary>
        /// 整数型枚举扩展方法，返回一个整数型枚举值匹配的所有枚举名称
        /// </summary>
        /// <returns></returns>
        public static string GetEnumNames(this int v, Type enumType, params int[] exclude)
        {
            string n = string.Empty;
            foreach (int i in Enum.GetValues(enumType))
            {
                if (exclude.Length > 0 && exclude.Where(a => a == i).Count() > 0) continue;
                if ((v & i) == i) n += (n == string.Empty ? "" : ",") + Enum.GetName(enumType, i);
            }
            return n;
        }
        /// <summary>
        /// 整数型枚举扩展方法，返回一个整数型枚举值匹配的所有枚举名称（反向列表）
        /// </summary>
        /// <returns></returns>
        public static string GetEnumNamesBF(this int v, Type enumType, params int[] exclude)
        {
            string[] s = v.GetEnumNames(enumType, exclude).Split(',');
            string s2 = string.Empty;
            for (int k = s.Length - 1; k >= 0; k--)
            {
                s2 = s2 + (s2 == string.Empty ? "" : ",") + s[k];
            }
            return s2;
        }

        /// <summary>
        /// 扩展方法：将枚举转成字典
        /// </summary>
        /// <param name="en"></param>
        /// <returns></returns>
        public static Dictionary<string, int> GetEnumListAll(this Enum en)
        {
            Dictionary<string, int> list = new Dictionary<string, int>();
            foreach (int i in Enum.GetValues(en.GetType()))
            {
                list.Add(Enum.GetName(en.GetType(), i), i);
            }
            return list;
        }

        /// <summary>
        /// 扩展方法：将枚举转成数据表（两列分别是name,value）
        /// </summary>
        /// <param name="en">必须为枚举类型</param>
        /// <returns></returns>
        public static DataTable GetEnumTableAll(this Enum en)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("name");
            dt.Columns.Add("value");
            //foreach (int v in Enum.GetValues(en)) dt.Rows.Add(Enum.GetName(en, v), v);
            //按枚举定义顺序
            foreach (var v in en.GetType().GetFields())
            {
                if (v.FieldType.IsEnum)
                {
                    dt.Rows.Add(v.Name, v.GetRawConstantValue());
                }
            }
            return dt;
        }


    }
}
